/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "lottie_render_gpu.h"
#include <dlfcn.h>

namespace LottieTurbo {

LottieGpuFun::LottieGpuFun()
{
    funcHandle_ = dlopen("libnative_drawing.so", RTLD_LAZY);
    if (funcHandle_ == nullptr) {
        DRAWING_LOGE("LottieGpuFun::LottieGpuFun funcHandle_ dlopen failed");
    }
    funcGpuCreate_ = reinterpret_cast<GpuCreate>(dlsym(funcHandle_, "OH_Drawing_GpuContextCreate"));
    funcGpuDestroy_ = reinterpret_cast<GpuDestroy>(dlsym(funcHandle_, "OH_Drawing_GpuContextDestroy"));
    funcGpuSurface_ = reinterpret_cast<GpuSurface>(dlsym(funcHandle_, "OH_Drawing_SurfaceCreateOnScreen"));
    funcGpuSurfaceFromContext_ =
        reinterpret_cast<GpuSurfaceFromContext>(dlsym(funcHandle_, "OH_Drawing_SurfaceCreateFromGpuContext"));
    funcGpuFlash_ = reinterpret_cast<GpuFlash>(dlsym(funcHandle_, "OH_Drawing_SurfaceFlush"));
}

LottieGpuFun::~LottieGpuFun()
{
    if (funcHandle_ != nullptr) {
        dlclose(funcHandle_);
    } else {
        DRAWING_LOGE("LottieGpuFun::~LottieGpuFun funcHandle_ dlclose failed");
    }
}

LottieGpuFun &LottieGpuFun::GetInstance()
{
    static LottieGpuFun instance;
    return instance;
}

OH_Drawing_Surface *LottieGpuFun::RenderGpuSurface(OH_Drawing_GpuContext *gpuContext, OH_Drawing_Image_Info imageInfo,
                                                   void *window)
{
    if (funcGpuSurface_ == nullptr) {
        DRAWING_LOGE("LottieGpuFun::RenderGpuFlash funcGpuSurface_ nullptr");
        return nullptr;
    }
    return funcGpuSurface_(gpuContext, imageInfo, window);
}

OH_Drawing_GpuContext *LottieGpuFun::RenderGpuCreate()
{
    if (funcGpuCreate_ == nullptr) {
        DRAWING_LOGE("LottieGpuFun::RenderGpuFlash funcGpuCreate_ nullptr");
        return nullptr;
    }
    return funcGpuCreate_();
}

void LottieGpuFun::RenderGpuDestroy(OH_Drawing_GpuContext *gpuContext)
{
    if (funcGpuDestroy_ == nullptr) {
        DRAWING_LOGE("LottieGpuFun::RenderGpuFlash funcGpuDestroy_ nullptr");
        return;
    }
    funcGpuDestroy_(gpuContext);
}

OH_Drawing_Surface *LottieGpuFun::RenderGpuSurfaceFromContext(OH_Drawing_GpuContext *gpuContext, bool flag,
                                                              OH_Drawing_Image_Info imageInfo)
{
    if (funcGpuSurfaceFromContext_ == nullptr) {
        DRAWING_LOGE("LottieGpuFun::RenderGpuFlash funcGpuSurfaceFromContext_ nullptr");
        return nullptr;
    }
    return funcGpuSurfaceFromContext_(gpuContext, flag, imageInfo);
}

void LottieGpuFun::RenderGpuFlash(OH_Drawing_Surface *surface)
{
    if (funcGpuFlash_ == nullptr) {
        DRAWING_LOGE("LottieGpuFun::RenderGpuFlash funcGpuFlash_ nullptr");
        return;
    }
    auto ret = funcGpuFlash_(surface);
    if (ret != OH_Drawing_ErrorCode::OH_DRAWING_SUCCESS) {
        DRAWING_LOGE("LottieGpuFun::RenderGpuFlash error code:%{public}d", ret);
    }
}

} // namespace LottieTurbo
